<?php
namespace app\test\controller;
use think\Controller;
use think\Session;
use think\Db;
/**
 * 第三方登录 案例
 * Class Syslogin
 * @package app\test\controller
 */
class Syslogin extends Controller
{
    public function index() {
        $url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/';
        Session::set('HTTP_URL_BACK',$url);
        return $this->fetch();
    }

    //登录地址
    public function login($type){
        if (!$type) $this->error('参数错误 ^_^');
        $sns  = \thinksdk\ThinkOauth::getInstance($type);
        $sns->setDisplay('default'); //此处为可选,若没有设置为mobile,则跳转的授权页面可能不适合手机浏览器访问
        //跳转到授权页面
        return redirect($sns->getRequestCodeURL());
    }


    /**
     * SNS 授权回调处理
     * @param $type sns类型
     * @param $code
     */
    public function callback($type, $code){
        if (!$type) $this->error('参数错误 ^_^');
        if(empty($code))  redirect("/");
        $sns  = \thinksdk\ThinkOauth::getInstance($type);
        //腾讯微博需传递的额外参数
        $extend = null;
        if($type == 'tencent'){
            $extend = ['openid' => $this->request->param("openid"), 'openkey' => $this->request->param("openkey")];
        }
        //获取 token 信息
        /**
         * [
         *   'access_token'=> 'xxxxxxxx',
         *   'expires_in' => token的生命时间
         * ]
         */
        //请妥善保管这里获取到的Token信息，方便以后API调用
        $token = $sns->getAccessToken();
        // 获取sns用户信息
        $sns_info = $sns->userinfo();
        if(is_array($token)){
            $this->_bang_handle($sns_info, $type, $token);
        }else{
            $this->success('登录失败！',$this->_get_login_redirect());
        }

    }

    /**
     * 获取上一次历史记录
     * @return mixed
     */
    private function _get_login_redirect(){
        return Session::get('HTTP_URL_BACK');
    }

    /**
     * 绑定第三方用户
     * @param $user_info sns用户信息
     * @param $type      sns类型
     * @param $token     sns token信息
     * @return \think\response\Redirect
     * @throws \think\Exception
     */
    private function _bang_handle($user_info, $type, $token){
        // 检测第三方用户表数据
        $type=strtolower($type);
        $find_oauth_user = Db::name('oauth_user')->where(["type"=>$type,"openid" => $user_info['openid']])->find();
        $need_register = true;
        if($find_oauth_user){
            // 第三方数据表存在直接登录
            $find_user = Db::name('users')->where(["uid" => $find_oauth_user['users_uid']])->find();
            if($find_user){
                $need_register = false;
                if($find_user['is_black']){
                    $this->error('用户已被锁定，请联系网站管理员！');
                }else{
                    Session::set('uid',$find_user['uid']);
                    Session::set('username',$find_user['uname']);
                    $this->redirect($this->_get_login_redirect());
                }
            } else {
                // 不存在,删除第三方表数据
                Db::name('users')->where(['id'=>$find_oauth_user['id']])->delete();
                $need_register = true;
            }
        }
        // 注册信息
        if($need_register){
            // 替换特定的字符
            $name = preg_replace('/😘+/is','',$user_info['name']);
            $user_data = [
                'uname' => $name . '_' . $type,
                'nickname' => $name . '_' . $type,
                'add_time' => time(),
                'user_type' => 2,
                'last_login_time' => time(),
                'password' => ''
            ];
            // 用户名唯一的情况下需要检测用户名,存在重新生成 TODO 具体业务具体处理
            $user_name = Db::name('users')->where(['uname' => $user_data['uname']])->value('uname');
            if ($user_name) {
                $rand_code = \Cocolait\CpMsubstr::rand_string(2,0);
                $user_data['uname'] = $name . '_' . $type . "_" . $rand_code;
            }
            // 将远程服务器头像,保存在自己的服务器中 TODO 具体业务具体处理
            $oData = \Cocolait\CpGet::getImage($user_info['head'],1);
            if (!$oData['error']) {
                $user_data['face'] = $oData['save_path'];
            } else {
                $user_data['face'] = $user_info['head'];
            }
            // 保存到用户中
            $user_insert_id = Db::name('users')->insertGetId($user_data);
            if($user_insert_id){
                // 保存第三方用户表
                $oauth_user_data = array(
                    'type' => $type,
                    'name' => $name . '_' . $type,
                    'head_img' => $user_info['head'],
                    'create_time' =>date("Y-m-d H:i:s"),
                    'users_uid' => $user_insert_id,
                    'last_login_time' => date("Y-m-d H:i:s"),
                    'last_login_ip' => \Cocolait\CpGet::get_client_ip(0,true),
                    'login_times' => 1,
                    'status' => 1,
                    'access_token' => $token['access_token'],
                    'expires_date' => (int)(time()+$token['expires_in']),
                    'openid' => $user_info['openid'],
                );
                $oauth_user_insert_id = Db::name('oauth_user')->insertGetId($oauth_user_data);
                if($oauth_user_insert_id){
                    Session::set('uid',$user_insert_id);
                    Session::set('username',$user_data['uname']);
                    $this->redirect('/');
                }else{
                    Db::name('users')->where(["uid" => $user_insert_id])->delete();
                    $this->error("登陆失败",$this->_get_login_redirect());
                }
            }else{
                $this->error("登陆失败",$this->_get_login_redirect());
            }

        }
    }


}
